 
package com.zdkj.subway.rca.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.util.DateUtils;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;


import com.zdkj.common.core.exceltools.MultipartFileToFile;

import com.zdkj.common.security.util.ObjectUtils;
import com.zdkj.subway.rca.entity.*;

import com.zdkj.subway.rca.mapper.SwCkElectronicReceiptTmpMapper;
import com.zdkj.subway.rca.service.SwCkElectronicReceiptService;
import com.zdkj.subway.rca.service.SwCkElectronicReceiptTmpService;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.text.ParseException;
import java.time.ZoneId;
import java.util.*;

/**
 * 电子回执单临时表
 *
 * @author stw
 * @date 2020-12-04 11:57:25
 */
@Service
public class SwCkElectronicReceiptTmpServiceImpl extends ServiceImpl<SwCkElectronicReceiptTmpMapper, SwCkElectronicReceiptTmp> implements SwCkElectronicReceiptTmpService {
    private static final Logger LOGGER = LoggerFactory.getLogger(SwCkElectronicReceiptTmpServiceImpl.class);
    private String parsePattern = "yyyy/M/d";

    @Autowired
    private SwCkElectronicReceiptService swCkElectronicReceiptService;

    @Override
    public Boolean saveBatchWithExcel(final File excelFile) throws Exception {
        List<Map<Integer, String>> listMap = EasyExcel.read(excelFile).sheet().headRowNumber(2).doReadSync();
        List<Map<String,String>> lineMap = this.baseMapper.selectLineMap();
        List<Map<String,String>> stationMap = this.baseMapper.selectStationMap();
        List<Map<String,String>> ticketMap = this.baseMapper.selecTicketMap();

        if (CollectionUtil.isNotEmpty(listMap)) {
            List<SwCkElectronicReceiptTmp> listDb = new ArrayList<>();
            MultipartFileToFile.delteTempFile(excelFile);
            for (int m = 0; m < listMap.size(); m++) {
                Map<Integer, String> data = listMap.get(m);
                // 返回每条数据的键值对 表示所在的列 和所在列的值
                LOGGER.info("读取到数据:{}", JSON.toJSONString(data));

                SwCkElectronicReceiptTmp tmpObj = new SwCkElectronicReceiptTmp();
                tmpObj.setBookkeepingTimeTmp(data.get(0));//记账日期
                tmpObj.setLineCodeTmp(data.get(1));
                tmpObj.setStationCodeTmp(data.get(2));

                tmpObj.setTicketName(data.get(3));
                tmpObj.setPaymentTypeTmp(data.get(4));

                tmpObj.setSaleNumberTmp(data.get(5));
                tmpObj.setSaleAmountTmp(data.get(6));

                tmpObj.setMailingCostTmp(data.get(7));
                tmpObj.setHandServiceMoneyTmp(data.get(8));
                tmpObj.setBankAccountBalanceTmp(data.get(9));

                if (StringUtils.isEmpty(tmpObj.getBookkeepingTimeTmp())) {
                    continue;
                }
                if (!parseDate(tmpObj.getBookkeepingTimeTmp())) {
                    continue;
                }

                final SwCkElectronicReceiptTmp obj = ObjectUtils.getDefaultObj(SwCkElectronicReceiptTmp.class);
                BeanUtils.copyProperties(tmpObj, obj, "creatorId", "creatorName");
                checkErr(obj,lineMap,stationMap,ticketMap);
                listDb.add(obj);

            }
            Map<String, Object> columnMap = new HashMap<>();
            columnMap.put("CREATOR_ID", listDb.get(0).getCreatorId());
            this.baseMapper.deleteByMap(columnMap);
            return this.saveBatch(listDb);

        }

        return false;
    }

    private String getLineCode (List<Map<String,String>> lineMap,String lineName) {
        for (Map<String,String> map : lineMap){
            if(lineName.equals(map.get("NAME"))){
                return map.get("CODE");
            }
        }
        return "";
    }

    private String getStationCode (List<Map<String,String>> stationMap,String stationName,String lineCode) {
        for (Map<String,String> map : stationMap){
            if(stationName.equals(map.get("NAME")) && lineCode.equals(map.get("LINE_CODE"))){
                return map.get("CODE");
            }
        }
        return "";
    }

    private String getTicketType (List<Map<String,String>> ticketMap,String ticketName) {
        for (Map<String,String> map : ticketMap){
            if(ticketName.equals(map.get("SUB_NAME"))){
                return map.get("SUB_EN_NAME");
            }
        }
        return "";
    }
    private String getUnitTicketPrice (List<Map<String,String>> ticketMap,String ticketName) {
        for (Map<String,String> map : ticketMap){
            if(ticketName.equals(map.get("SUB_NAME"))){
                return map.get("TICKET_AMOUNT");
            }
        }
        return "";
    }

    private void checkErr(SwCkElectronicReceiptTmp obj, List<Map<String,String>> lineMap, List<Map<String,String>> stationMap,List<Map<String,String>> ticketMap) {
        //更新字段
        String bookkeepingTimeTmp = obj.getBookkeepingTimeTmp();
        try {
            Date tradeDate = DateUtils.parseDate(bookkeepingTimeTmp, parsePattern);
            obj.setBookkeepingTime(tradeDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate());
        } catch (Exception e) {
            obj.setErrMsg("记账日期 为空或格式错误");
        }

        if(StringUtils.isNotEmpty(obj.getLineCodeTmp())){
            String lineCode = getLineCode(lineMap,obj.getLineCodeTmp());
            if(StringUtils.isNotEmpty(lineCode)){
                obj.setLineCode(lineCode);
            } else {
                obj.setErrMsg("线路名称 为空或不规范");
            }

        } else {
            obj.setErrMsg("线路名称 为空");
        }

        if(StringUtils.isNotEmpty(obj.getStationCodeTmp()) && StringUtils.isNotEmpty(obj.getLineCode())){
            String stationCode = getStationCode(stationMap,obj.getStationCodeTmp(),obj.getLineCode());
            if(StringUtils.isNotEmpty(stationCode)){
                obj.setStationCode(stationCode);
            } else {
                obj.setErrMsg("车站名称 为空或不规范");
            }
        } else {
            obj.setErrMsg("车站名称 为空");
        }

        if(StringUtils.isNotEmpty(obj.getTicketName())){
            String ticketType = getTicketType(ticketMap,obj.getTicketName());
            if(StringUtils.isNotEmpty(ticketType)){
                obj.setTicketType(ticketType);
            } else {
                obj.setErrMsg("票种名称 为空或不规范，票种CODE错误");
            }
            String unitTicketPrice = getUnitTicketPrice(ticketMap,obj.getTicketName());
            if(StringUtils.isNotEmpty(unitTicketPrice)){
                obj.setUnitTicketPrice(new BigDecimal(unitTicketPrice));
            } else {
                obj.setErrMsg("票种名称 为空或不规范, 票价错误");
            }
        } else {
            obj.setErrMsg("票种名称 为空");
        }

        if(StringUtils.isNotEmpty(obj.getPaymentTypeTmp())){
            if(obj.getPaymentTypeTmp().contains("现金")){
                obj.setPaymentType("10");
            } else if(obj.getPaymentTypeTmp().contains("支付宝")) {
                obj.setPaymentType("12");
            } else if(obj.getPaymentTypeTmp().contains("微信")) {
                obj.setPaymentType("13");
            } else if(obj.getPaymentTypeTmp().contains("银行") || obj.getPaymentTypeTmp().contains("银联")) {
                obj.setPaymentType("14");
            } else {
                obj.setErrMsg("支付方式 为空或不规范");
            }
        } else {
            obj.setErrMsg("支付方式 为空");
        }
        try {
            if (StringUtils.isNotEmpty(obj.getSaleNumberTmp())) {
                obj.setSaleNumber(Integer.parseInt(obj.getSaleNumberTmp()));
            } else {
                obj.setErrMsg("售卖张数 为空");
            }
        } catch (Exception e) {
            obj.setErrMsg("售卖张数 为空或格式错误");
        }

        try {
            BigDecimal num = new BigDecimal("100");

            String saleAmountTmp = StringUtils.isEmpty(obj.getSaleAmountTmp()) ? "0" : obj.getSaleAmountTmp();
            BigDecimal saleAmount = new BigDecimal(saleAmountTmp).setScale(2, BigDecimal.ROUND_HALF_UP);
            saleAmount = saleAmount.multiply(num);
            obj.setSaleAmount(saleAmount);

            String mailingCostTmp =  StringUtils.isEmpty(obj.getMailingCostTmp()) ? "0" : obj.getMailingCostTmp();
            BigDecimal mailingCost = new BigDecimal(mailingCostTmp).setScale(2, BigDecimal.ROUND_HALF_UP);
            mailingCost = mailingCost.multiply(num);
            obj.setMailingCost(mailingCost);

            String handServiceMoneyTmp =  StringUtils.isEmpty(obj.getHandServiceMoneyTmp()) ? "0" : obj.getHandServiceMoneyTmp();
            BigDecimal handServiceMoney = new BigDecimal(handServiceMoneyTmp).setScale(2, BigDecimal.ROUND_HALF_UP);
            handServiceMoney = handServiceMoney.multiply(num);
            obj.setHandServiceMoney(handServiceMoney);

            String bankAccountBalanceTmp =  StringUtils.isEmpty(obj.getBankAccountBalanceTmp()) ? "0" : obj.getBankAccountBalanceTmp();
            BigDecimal bankAccountBalance = new BigDecimal(bankAccountBalanceTmp).setScale(2, BigDecimal.ROUND_HALF_UP);
            bankAccountBalance = bankAccountBalance.multiply(num);
            obj.setBankAccountBalance(bankAccountBalance);

        } catch (Exception e) {
            obj.setErrMsg("金额 为空或格式错误");
        }

        //平台
        obj.setReturnOrderType("3");
        //扣除手续费后金额 = 售卖金额+邮寄费-手续费
        obj.setDeductHandServiceMoney(obj.getSaleAmount().add(obj.getMailingCost()).subtract(obj.getHandServiceMoney() ));

        obj.setDataType("3");
        obj.setConfirmStatus("0");
        obj.setReturnNumber("");
        //差异金额（银行账户金额-扣除手续费金额）
        obj.setDiffElecAmount(obj.getBankAccountBalance().subtract(obj.getDeductHandServiceMoney()));

        //判断数据是否存在
        SwCkElectronicReceipt swCkElectronicReceipt = new SwCkElectronicReceipt();
        BeanUtils.copyProperties(obj, swCkElectronicReceipt, "creatorId","creatorName","createTime");
        List<SwCkElectronicReceipt> list = swCkElectronicReceiptService.list(Wrappers.query(swCkElectronicReceipt));
        if (list != null && !list.isEmpty()) {
            obj.setErrMsg("数据已存在");
        }
    }

    private boolean parseDate(String string) {
        boolean convertSuccess = true;
        if (string == null) {
            return false;
        }

        try {
            DateUtils.parseDate(string, parsePattern);
        } catch (ParseException e) {
            convertSuccess = false;
        }
        return convertSuccess;
    }

    @Override
    public void saveBatchWithExcelOk(Integer creatorId) {
        //导入先删除
        this.baseMapper.deleteBatchWithExcelOk(creatorId);
        //导入先删除再添加包括重复的
        this.baseMapper.saveBatchWithExcelOkRepeat(creatorId);
        //this.baseMapper.saveBatchWithExcelOk(creatorId);
        saveBatchWithExcelCancel(creatorId);
    }

    @Override
    public void saveBatchWithExcelCancel(Integer creatorId) {
        Map<String, Object> columnMap = new HashMap<>();
        columnMap.put("CREATOR_ID", creatorId);
        this.baseMapper.deleteByMap(columnMap);
    }

    @Override
    public void exportTamplates(HttpServletResponse response) {
        String  verifyConfirmName = "西安地铁APP线上售卖纪念册对账汇总表";
        String  tableName = "sw_ck_electronic_receipt";

        BufferedInputStream br = null;
        OutputStream out = null;
        try {
            response.reset(); // 非常重要
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("utf-8");
            final String fileName = URLEncoder.encode(verifyConfirmName, "UTF-8");
            response.setHeader("Content-disposition", "attachment;filename=" + fileName + System.currentTimeMillis() + ".xlsx");

            br =  new BufferedInputStream(this.getClass().getResourceAsStream("/static/excel/template/import/" + tableName + ".xlsx"));

            byte[] buf = new byte[1024];
            int len = 0;

            out = response.getOutputStream();
            while ((len = br.read(buf)) > 0) {
                out.write(buf, 0, len);
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if(out != null) {
                try {
                    out.close();
                } catch (IOException ioe) {
                    ioe.printStackTrace();
                }
            }
            if(br != null){
                try {
                    br.close();
                } catch (IOException ioe) {
                    ioe.printStackTrace();
                }
            }
        }
    }
}
